home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-08-08 | 10.4 KB | 344 lines | [TEXT/KAHL] |
- /************************************************************
- *
- * Created: Sunday, January 20, 1991 4:11:08 PM
- * CNameIndex.cp
- * C++ class implementation for name-based index class
- *
- *
- * Copyright Neologic Systems 1992-1994
- * All rights reserved
- *
- *
- * Within a class, references to permanent objects are kept in
- * a sorted list called an index. The default sorting order in
- * an index is ascending by ID value, however other sorting
- * orders are possible. The class CNameIndex implements a
- * secondary index which organizes objects in ascending order
- * by name.
- *
- ***********************************************************/
-
- #ifdef qNeoMacintosh
- #include <Packages.h>
- #endif
- #include "NeoTypes.h"
- #include CNeoMetaClassH
- #include CNeoSelectH
- #include CNeoStreamH
- #include CNeoDatabaseH
- #include "CNameIndex.h"
- #include CNeoClassH
- #include "CPerson.h"
-
- #ifndef NeoInherited
- #define NeoInherited CNeoNode
- #endif
-
- /* ****************************************************************** */
- /** Instance Methods **/
- /* ****************************************************************** */
-
- #pragma segment NeoCreate
- CNameIndex::CNameIndex(const short aCount, CNeoNode *aParent, const NeoID aID)
- : CNeoNode(aCount, TRUE, aParent)
- {
- fID = aID;
- }
-
- /*
- * Allocate and initialize a new instance.
- */
- #pragma segment NeoCreate
- CNeoPersist *CNameIndex::New(void)
- {
- CNameIndex * object;
-
- object = new CNameIndex(0, nil, 0);
-
- return object;
- }
-
- /*
- * Return the class ID for this kind of object.
- */
- #pragma segment NeoInfo
- NeoID CNameIndex::getClassID(void) const
- {
- return kNameIndexID;
- }
-
- /*
- * The getEntryValue method can be used to obtain the value of a data member of
- * the entry referred to by aIndex. The aName argument is a tag which identifies
- * the data member, and aType refers to the format in which the value is to be
- * returned. Finally, aValue is a pointer to a buffer into which the value should
- * be returned.
- */
- #pragma segment NeoSearch
- OSErr CNameIndex::getEntryValue(const short aIndex, const NeoTag aName, const NeoTag aType, void *aValue)
- {
- OSErr err = noErr;
-
- NeoAssert(aIndex >= 0 && aIndex < fCount);
- switch (aName) {
- case pNeoName:
- NeoAssert(aType == kNeoNativeStringType);
- *(CNeoString *)aValue = fEntry[aIndex].fName;
- break;
-
- case pNeoID:
- NeoAssert(aType == kNeoLongType);
- *(NeoID *)aValue = fEntry[aIndex].fID;
- break;
-
- default:
- err = NeoInherited::getEntryValue(aIndex, aName, aType, aValue);
- }
-
- return err;
- }
-
- /*
- * Return the size of the object in memory.
- */
- #pragma segment NeoInfo
- long CNameIndex::getLength(void) const
- {
- return sizeof(CNameIndex);
- }
-
- /*
- * This method returns the amount of file space the object occupies in the file. It
- * differs from the getLength in that getLength returns the size of the object in
- * memory.
- */
- #pragma segment NeoInfo
- long CNameIndex::getFileLength(void) const
- {
- return (kNeoNodeFileLength + (sizeof(NameIndexEntry) * kNeoDefaultNodeEntryCount));
- }
-
- /* ****************************************************************** */
- /** I/O Methods **/
- /* ****************************************************************** */
-
- /*
- * The readObject method is used to read in the permanent data members of the
- * object from the given stream. In most cases, this method operates without concern
- * for the type of stream the data values are coming from. As a result, this method
- * is capable of reading from such diverse sources as the data fork of a file, a
- * resource fork, an AppleEvent, the clipboard, a memory block, and so on.
- *
- * The aTag argument indicates how much information to read from the stream.
- * It is sometimes sufficient to read in a minimum amount of data and have all
- * other data be read in on demand. Other times it is necessary to read all the
- * data immediately as the stream may not be available later.
- *
- * The two tag values that are currently used are kNeoObjectTag and kNeoAllTag.
- *
- * The value kNeoObjectTag means that only those values of immediate interest
- * need to be read from the stream, though implementations of readObject may read
- * in additional data member values if they wish.
- *
- * The value kNeoAllTag indicates that all data member values for this class
- * should be read in to the stream.
- */
- #pragma segment NeoRead
- void CNameIndex::readObject(CNeoStream *aStream, const NeoTag aTag)
- {
- short index;
-
- NeoInherited::readObject(aStream, aTag);
-
- for (index = 0; index < fCount; index++) {
- fEntry[index].fID = aStream->readLong();
- aStream->readNativeString(fEntry[index].fName, sizeof(fEntry[index].fName));
- }
- }
-
- /*
- * The writeObject method is used to write to the permanent data members of the
- * object from the given stream. In most cases, this method operates without concern
- * for the type of stream the data values are coming from. As a result, this method
- * is capable of writing to such diverse sources as the data fork of a file, a
- * resource fork, an AppleEvent, the clipboard, a memory block, and so on.
- *
- * The aTag argument indicates how much information to write to the stream.
- * It is sometimes sufficient to write out only those parts that are dirty. Other
- * times it is necessary to write all the data, as when doing Save As operation
- * or when communicating an object's complete state across and RPC channel.
- *
- * The two tag values that are currently used are kNeoObjectTag and kNeoAllTag.
- *
- * The value kNeoObjectTag means that only those values of immediate interest
- * need to be written to the stream, though implementations of writeObject may
- * write out additional data member values if they wish.
- *
- * The value kNeoAllTag indicates that all data member values for this class
- * should be writen out to the stream.
- */
- #pragma segment NeoWrite
- void CNameIndex::writeObject(CNeoStream *aStream, const NeoTag aTag)
- {
- short index;
-
- NeoInherited::writeObject(aStream, aTag);
-
- for (index = 0; index < fCount; index++) {
- aStream->writeLong(fEntry[index].fID);
- aStream->writeNativeString(fEntry[index].fName, sizeof(fEntry[index].fName));
- }
- }
-
- /* ****************************************************************** */
- /** Object List Management Methods **/
- /* ****************************************************************** */
-
-
- /*
- * This method reads in the object referred to by the specified entry. Secondary
- * indices do not refer directly to the object in the file or in memory. Instead,
- * the specified entry of this index contains the information necessary to
- * locate the object using the primary index.
- *
- * Note: The getObject method is not supposed to add a reference to the object.
- * As such, the reference added by FindByID is removed before passing the object
- * back to our caller.
- */
- #pragma segment NeoSearch
- CNeoPersist *CNameIndex::getObject(const short aIndex)
- {
- CNeoPersist * object;
- CNeoIDSelect key(fEntry[aIndex].fID);
-
- object = (CNeoPersist *)CNeoClass::FindObject(CNeoMetaClass::FObjClassID, &key, FALSE, nil, nil);
- object->unrefer(); // Our caller will add the reference if it wants to
-
- return object;
- }
-
- /*
- * This method locates the leaf of the index tree into which the object
- * should be added. Then it fills in the attributes of the new entry and calls
- * insertEntry() to add it in the proper place in the list.
- */
- #pragma segment NeoAdd
- CNeoNode *CNameIndex::insertObject(const short aIndex, CNeoPersist *aObject)
- {
- NeoID oldClassID;
- CNeoNode * newRoot = nil;
- CPerson * person = (CPerson *)aObject;
- CNeoString name;
- NameIndexEntry newEntry;
-
- newEntry.fID = person->fID;
- ((CPerson *)aObject)->getName(newEntry.fName);
-
- oldClassID = CNeoMetaClass::FSysClassID;
- CNeoMetaClass::FSysClassID = kNameIndexID;
-
- newRoot = insertEntry(aIndex, (Ptr)&newEntry);
- #ifdef qNeoDebug
- if (newRoot)
- NeoVerifyNode(newRoot);
- #endif
-
- CNeoMetaClass::FSysClassID = oldClassID;
-
- return newRoot;
- }
-
- /*
- * The metaclass object of all persistent classes need to be able to determine
- * the primary selection criteria of that class. This static function is called
- * through the index class's metaclass object. It is used to: 1) whether the
- * index can perform a binary search using the given select key, and 2) to
- * obtain a select key for locating the proper index entry for the given
- * object.
- */
- #pragma segment NeoSearch
- void *CNameIndex::KeyManager(const NeoKeyOp aOp, ...)
- {
- va_list argptr; // pointer to argument list.
- NeoSelectType selectType;
- void * value = nil;
- CNeoSelect * key;
- CPerson * person;
- CNeoString name;
-
- va_start(argptr, aOp);
- switch (aOp) {
- case kNeoCanSupport:
- key = va_arg(argptr, CNeoSelect *);
- selectType = key->getSelectType();
- if (selectType == pNeoName)
- value = (void *)(unsigned char)TRUE;
- #ifdef qNeoShare
- else if (selectType == kNeoAEKeySelect &&
- ((CNeoAEKeySelect *)key)->getAEKeyword() == pNeoName)
- value = (void *)(unsigned char)TRUE;
- #endif
- else
- value = NeoInherited::KeyManager(kNeoCanSupport, key, selectType);
- break;
-
- case kNeoGetKey:
- person = va_arg(argptr, CPerson *);
- person->getName(name);
- value = (void *)new CNeoNameSelect(name);
- break;
- }
- va_end(argptr);
-
- return value;
- }
-
- /* ****************************************************************** */
- /** Entry Management Methods **/
- /* ****************************************************************** */
-
- /*
- * This function provides a mechanism for determining the size of entries for
- * a particular node.
- */
- #pragma segment NeoChange
- short CNameIndex::getEntrySize(void) const
- {
- return sizeof(NameIndexEntry);
- }
-
- #ifdef qNeoDebug
- /* ****************************************************************** */
- /** Debugging Methods **/
- /* ****************************************************************** */
-
- /*
- * All subclasses of CNeoPersist should override the verify method to
- * perform a consistency check on objects. This method should make as
- * many general assertions as possible.
- *
- * CNeoParentNNameIndex's verify checks that the entries are sorted
- * in ascending order by the fields fParentID and fName.
- * aValue is assumed to be a pointer to the last entry in the previous
- * sibling node.
- * The return value is a pointer to the last entry in this node.
- */
- const void *CNameIndex::verify(const void *aValue) const
- {
- short index;
- const NameIndexEntry * entry = (NameIndexEntry *)aValue;
-
- for (index = 0; index < fCount; index++) {
- if (entry)
- NeoAssert(entry->fName <= fEntry[index].fName);
- entry = &fEntry[index];
- }
-
- // CNeoNode::verify assumes parameter to be the current size of the database
- NeoInherited::verify(nil);
-
- return entry;
- }
- #endif
-
-